//************************************************************************************************************************
// Sketch name   : OD-Alarm
// Version       : 0.2.0
// Author        : astroz78 & osmosis
// Creation date : 27-02-2010
// Release note  : 27-02-2010 0.1.0: Prima versione
//                 05-03-2010 0.2.0: Aggiunta classe LedPanel e inserita gestione (solo LED stato)
//                 07-03-2010 0.2.1: Aggiunti commenti e documentazione versioni
//************************************************************************************************************************

         //********************//
         // External Libreries //
         //********************//
#include "ODAZone.h"
#include "ODARemote.h"
#include "ODASiren.h"
#include "ODADialer.h"
#include "ODALedPanel.h"
#include "ODBuzzer.h"

         //***********//
         // Constants //
         //***********//

//Arduino ports configurazion
const uint8_t      PORT_REMOTE_A = 43;
const uint8_t      PORT_REMOTE_B = 41;
const uint8_t      PORT_BUZZER = 2;
const uint8_t      PORT_SIREN_EXT_REAR = 3;
const uint8_t      PORT_SIREN_EXT_FRONT = 4;
const uint8_t      PORT_SIREN_INT = 5;
const uint8_t      PORT_DIALER_L1 = 6;
const uint8_t      PORT_DIALER_L2 = 7;
const uint8_t      PORT_DIALER_L3 = 8;
const uint8_t      PORT_DIALER_L4 = 9;
const uint8_t      PORT_DIALER_S1 = 10;
const uint8_t      PORT_DIALER_S2 = 11;
const uint8_t      PORT_DIALER_BK = 12;

//Utility constants
const uint8_t      OFF = 0;
const uint8_t      ON  = 1;

const uint8_t      OPENED = 0;
const uint8_t      CLOSED = 1;

//Other constants
const uint8_t      NUM_ZONE = 7;

         //***********//
         // Variables //
         //***********//

uint8_t dialerCall[4] = { PORT_DIALER_L1, PORT_DIALER_L2, PORT_DIALER_L3, PORT_DIALER_L4 };
uint8_t dialerSms[2]  = { PORT_DIALER_S1, PORT_DIALER_S2 };

Zone        zones[NUM_ZONE];
Buzzer      buzzer;
Remote      remote;
Siren       sirenExtFront;
Siren       sirenExtRear;
Siren       sirenInt;
Dialer      dialer;
LedPanel    ledPanel;

void setup() {
  Serial.begin(9600);

  //Carica la configurazione (sensori > zone)
  loadConfiguration();

  //Inizializzazione classe gestione buzzer
  buzzer.init(PORT_BUZZER);
  
  //Inizializzazione classe gestione radiocomando
  remote.init(PORT_REMOTE_A, PORT_REMOTE_B);
  
  //Inizializzazione classi gestione sirene
  sirenExtFront.init(PORT_SIREN_EXT_FRONT, GENERIC_OUTDOOR);
  sirenExtRear.init(PORT_SIREN_EXT_REAR, GENERIC_OUTDOOR);
  sirenInt.init(PORT_SIREN_INT, GENERIC_INDOOR);
  
  //Inizializzazione classe gestione combinatore
  dialer.init(dialerCall, dialerSms, PORT_DIALER_BK);
  
  //Inizializzazione classe gestione pannello LED
  ledPanel.init(53, 50, 51);
    
  //Attivazione zona antitamper
  zones[0].enable();
}

void loop() {
  //Servizi
  buzzer.service();
  remote.service();
  sirenExtFront.service();
  sirenExtRear.service();
  sirenInt.service();
  ledPanel.service();

  if (remote.getPressA()) buzzer.beep(SHORT_BEEP);
  
  //Gestione "comando di attivazione" da radiocomando (pulsante A)
  int remoteCommand = remote.getCommand();
  if (remoteCommand>0) {
    buzzer.beep(LONG_BEEP);
    dialer.enable();
    ledPanel.startBlink(0, 0, BLINK_SLOW);  
    
    if (remoteCommand > 0) {
      zones[1].enable();
      zones[3].enable();
      zones[5].enable();
    }
    
    if (remoteCommand == 1) {
      zones[2].enable();
      zones[4].enable();
      zones[6].enable();
    }
  }
  
  //Gestione "comando di disattivazione" da radiocomando (pulsante B)
  if (remote.getPressB()) {
    buzzer.beep(LONG_BEEP);
    ledPanel.turnOff(0, 0);
    
    zones[1].disable();
    zones[2].disable();
    zones[3].disable();
    zones[4].disable();
    zones[5].disable();
    zones[6].disable();
    
    sirenExtFront.stopAlarm();
    sirenExtRear.stopAlarm();
    sirenInt.stopAlarm();
    
    dialer.reset();
  }
   
  //Scansione zone abilitate
  for (int z = 0; z < NUM_ZONE; z++) {
    if (zones[z].isEnabled()) {

      //Se la zona è in allarme, scatena gli eventi di segnalazione (sirena + combinatore)
      if (zones[z].isAlarm()) {
        
        //Inizia i cicli di allarme per la sirena esterna (fronte)
        sirenExtFront.startAlarm();
        
        //Se è andata in allarme la zona antisabotaggio, oltre alla sirena fronte
        //faccio partire anche quella sul retro
        if (z == 0) {
          sirenExtRear.startAlarm();
          dialer.call(1);
        }
        
        //Invio chiamata tramite combinatore
        if (z == 1 || z == 3 || z == 5) dialer.call(2);
        if (z == 2 || z == 4 || z == 6) dialer.call(3);

        //Aggiornamento pannello LED per segnalazione memoria allarme
        ledPanel.startBlink(0, 0, BLINK_FAST);
      }
    }
  }
}


void loadConfiguration() {
  //Zona 0 - ANTITAMPER
  zones[0].addSensor(55); //Antitamper sirena EXT Retro 
  zones[0].addSensor(56); //Antitamper sirena EXT Fronte
  zones[0].addSensor(57); //Antitamper centrale + sirena INT
  zones[0].addSensor(58); //Antitamper combinatore
  zones[0].addSensor(59); //Antitamper PS
  zones[0].addSensor(60); //Antitamper PT
  zones[0].addSensor(61); //Antitamper PM

  //Zona 1 - PERIMETRALE PM
  zones[1].addSensor(62); //Finestra camera PM
  zones[1].addSensor(63); //Finestra bagno PM
  zones[1].addSensor(64); //Finestra cameretta PM
  
  //Zona 2 - VOLUMETRICA PM
  zones[2].addSensor(65); //PIR camera PM
  zones[2].addSensor(66); //PIR disimpegno PM
  zones[2].addSensor(67); //PIR cameretta PM

  //Zona 3 - PERIMETRALE PT
  zones[3].addSensor(32); //Persiana cucina PT
  zones[3].addSensor(34); //Persiana camera PT
  zones[3].addSensor(36); //Inferriata salone PT
  zones[3].addSensor(38); //Persiana corridoio PT
  zones[3].addSensor(40); //Persiana bagno PT 
  zones[3].addSensor(42); //Finestra cucina PT 
  zones[3].addSensor(44); //Finestra camera PT
  zones[3].addSensor(46); //Finestra salone PT
  zones[3].addSensor(48); //Finestra corridoio PT
  zones[3].addSensor(68); //Finestra bagno PT
  zones[3].addSensor(69); //Porta blindata PT
  
  //Zona 4 - VOLUMETRICA PT
  zones[4].addSensor(22); //PIR Cucina PT
  zones[4].addSensor(24); //PIR Camera PT
  zones[4].addSensor(26); //PIR Salone PT
  zones[4].addSensor(28); //PIR Corridoio PT
  zones[4].addSensor(30); //PIR Corridoio PT
  
  //Zona 5 - PERIMETRALE PS
  zones[5].addSensor(31); //Persiana studio PS
  zones[5].addSensor(33); //Inferriata cucina PS
  zones[5].addSensor(35); //Inferriata salone PS
  zones[5].addSensor(37); //Inferriata bagno PS
  zones[5].addSensor(39); //Finestra studio PS
  zones[5].addSensor(45); //Porta blindata PS
  
  //Zona 6 - VOLUMETRICA PS
  zones[6].addSensor(23); //PIR Corridoio PS
  zones[6].addSensor(25); //PIR Corridoio PS
  zones[6].addSensor(27); //PIR Salone PS
  zones[6].addSensor(29); //PIR Studio PS
}
